﻿
namespace IssueVision.Data.Web
{
    using System;
    using System.Linq;
    using System.ServiceModel.DomainServices.Server;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;

    [EnableClientAccess]
    public class PasswordResetService : LinqToEntitiesDomainService<IssueVisionEntities>
    {
        /// <summary>
        /// Return password question for the user name
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        [Query(IsComposable = false)]
        public PasswordResetUser GetUserByName(string userName)
        {
            User foundUser = ObjectContext.Users.FirstOrDefault(u => u.Name == userName);

            return foundUser != null
                       ? new PasswordResetUser
                       {
                           Name = foundUser.Name,
                           PasswordQuestion = foundUser.PasswordQuestion
                       }
                       : null;
        }

        /// <summary>
        /// Update user information to the database
        /// User information can only be updated if the user
        /// question/answer matches.
        /// </summary>
        [Update]
        public void UpdateUser(PasswordResetUser passwordResetUser)
        {
            // Search user from database by name
            User foundUser = ObjectContext.Users.FirstOrDefault(u => u.Name == passwordResetUser.Name);

            if (foundUser != null)
            {
                // generate password answer hash
                string passwordAnswerHash = HashHelper.ComputeSaltedHash(passwordResetUser.PasswordAnswer, foundUser.PasswordAnswerSalt);

                if ((string.Equals(passwordResetUser.PasswordQuestion, foundUser.PasswordQuestion, StringComparison.Ordinal)) &&
                    (string.Equals(passwordAnswerHash, foundUser.PasswordAnswerHash, StringComparison.Ordinal)))
                {
                    // Password answer matches, so save the new user password
                    // Re-generate password hash and password salt
                    foundUser.PasswordSalt = HashHelper.CreateRandomSalt();
                    foundUser.PasswordHash = HashHelper.ComputeSaltedHash(passwordResetUser.NewPassword, foundUser.PasswordSalt);

                    // re-generate passwordAnswer hash and passwordAnswer salt
                    foundUser.PasswordAnswerSalt = HashHelper.CreateRandomSalt();
                    foundUser.PasswordAnswerHash = HashHelper.ComputeSaltedHash(passwordResetUser.PasswordAnswer, foundUser.PasswordAnswerSalt);
                }
                else
                    throw new UnauthorizedAccessException(ErrorResources.PasswordQuestionDoesNotMatch);
            }
            else
                throw new UnauthorizedAccessException(ErrorResources.NoUserFound);
        }
    }
}
